package org.canaan.quartz;

import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.SimpleTrigger;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.springframework.core.Constants;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.Map;

/**
 @Author Canaan
 @Date 2018/3/16 */
public class SimpleTriggerBuilder {
    private static final Constants constants = new Constants(SimpleTrigger.class);
    private String    name;
    private String    group;
    private JobDetail jobDetail;
    private JobDataMap jobDataMap = new JobDataMap();
    private Date startTime;
    private long startDelay;
    private long repeatInterval;
    private int repeatCount = -1;
    private int    priority;
    private int    misfireInstruction;
    private String description;


    public SimpleTriggerBuilder setName(String name) {
        this.name = name;
        return this;
    }

    public SimpleTriggerBuilder setGroup(String group) {
        this.group = group;
        return this;
    }

    public SimpleTriggerBuilder setJobDetail(JobDetail jobDetail) {
        this.jobDetail = jobDetail;
        return this;
    }

    public JobDataMap getJobDataMap() {
        return this.jobDataMap;
    }

    public SimpleTriggerBuilder setJobDataMap(JobDataMap jobDataMap) {
        this.jobDataMap = jobDataMap;
        return this;
    }

    public SimpleTriggerBuilder setJobDataAsMap(Map<String, ?> jobDataAsMap) {
        this.jobDataMap.putAll(jobDataAsMap);
        return this;
    }

    public SimpleTriggerBuilder setStartTime(Date startTime) {
        this.startTime = startTime;
        return this;
    }

    public SimpleTriggerBuilder setStartDelay(long startDelay) {
        Assert.isTrue(startDelay >= 0L, "Start delay cannot be negative");
        this.startDelay = startDelay;
        return this;
    }

    public SimpleTriggerBuilder setRepeatInterval(long repeatInterval) {
        this.repeatInterval = repeatInterval;
        return this;
    }

    public SimpleTriggerBuilder setRepeatCount(int repeatCount) {
        this.repeatCount = repeatCount;
        return this;
    }

    public SimpleTriggerBuilder setPriority(int priority) {
        this.priority = priority;
        return this;
    }

    public SimpleTriggerBuilder setMisfireInstruction(int misfireInstruction) {
        this.misfireInstruction = misfireInstruction;
        return this;
    }

    public SimpleTriggerBuilder setMisfireInstructionName(String constantName) {
        this.misfireInstruction = constants.asNumber(constantName).intValue();
        return this;
    }

    public SimpleTriggerBuilder setDescription(String description) {
        this.description = description;
        return this;
    }


    public SimpleTrigger build() {

        if (this.group == null) {
            this.group = "DEFAULT";
        }

        if (this.jobDetail != null) {
            this.jobDataMap.put("jobDetail", this.jobDetail);
        }

        if (this.startDelay > 0L || this.startTime == null) {
            this.startTime = new Date(System.currentTimeMillis() + this.startDelay);
        }

        SimpleTriggerImpl sti = new SimpleTriggerImpl();
        sti.setName(this.name);
        sti.setGroup(this.group);
        if (this.jobDetail != null) {
            sti.setJobKey(this.jobDetail.getKey());
        }

        sti.setJobDataMap(this.jobDataMap);
        sti.setStartTime(this.startTime);
        sti.setRepeatInterval(this.repeatInterval);
        sti.setRepeatCount(this.repeatCount);
        sti.setPriority(this.priority);
        sti.setMisfireInstruction(this.misfireInstruction);
        sti.setDescription(this.description);
        return sti;
    }

}
